package xx.stream.use;

import xx.stream.entity.Student;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Classname StreamUse
 * @Description TODO
 * @Date 2023/7/21 17:32
 * @Created by wangxianlin
 */
public class StreamUse {

    public static void main(String[] args) {
        map();
    }

    /** TODO **************************************  Stream.of **************************************  */

    /**
     * 将流转换为list。还有toSet()，toMap()等。及早求值。
     */
    public static void collect() {
        List<Student> studentList = Stream.of(
                        new Student("路飞", 22, 175),
                        new Student("红发", 40, 180),
                        new Student("白胡子", 50, 185))
                .collect(Collectors.toList());
        System.out.println(studentList);
    }


    /** TODO **************************************  filter **************************************  */

    /**
     * 起过滤筛选的作用。内部就是Predicate接口。惰性求值。
     */
    public static void filter() {
        List<Student> students = new ArrayList<>(3);
        students.add(new Student("路飞", 22, 175));
        students.add(new Student("红发", 40, 180));
        students.add(new Student("白胡子", 50, 185));

        List<Student> list = students.stream()
                .filter(student -> student.getStature() < 180)
                // 将流转换为list
                .collect(Collectors.toList());
        System.out.println(list);
    }

    /** TODO **************************************  map **************************************  */

    /**
     * 转换功能，内部就是Function接口。惰性求值
     */
    public static void map() {
        List<Student> students = new ArrayList<>(3);
        students.add(new Student("路飞", 22, 175));
        students.add(new Student("红发", 40, 180));
        students.add(new Student("白胡子", 50, 185));

        List<String> names = students.stream().map(student -> student.getName())
                .collect(Collectors.toList());
        System.out.println(names);
    }

    /**
     * 将多个Stream合并为一个Stream。惰性求值
     */
    public static void flatMap() {

    }

    /** TODO **************************************  max、min **************************************  */

    /**
     * max、min接收一个Comparator（例子中使用java8自带的静态函数，只需要传进需要比较值即可。）并且返回一个Optional对象，该对象是java8新增的类，专门为了防止null引发的空指针异常。
     * 可以使用max.isPresent()判断是否有值；可以使用max.orElse(new Student())，当值为null时就使用给定值；也可以使用max.orElseGet(() -> new Student());这需要传入一个Supplier的lambda表达式。
     */
    public static void minAndMax() {
        List<Student> students = new ArrayList<>(3);
        students.add(new Student("路飞", 22, 175));
        students.add(new Student("红发", 40, 180));
        students.add(new Student("白胡子", 50, 185));

        Optional<Student> max = students.stream()
                .max(Comparator.comparing(stu -> stu.getAge()));
        Optional<Student> min = students.stream()
                .min(Comparator.comparing(stu -> stu.getAge()));
        //判断是否有值
        if (max.isPresent()) {
            System.out.println(max.get());
        }
        if (min.isPresent()) {
            System.out.println(min.get());
        }

    }


    /** TODO **************************************  count 统计功能 **************************************  */

    /**
     * 统计功能，一般都是结合filter使用，因为先筛选出我们需要的再统计即可
     */
    public static void count() {
        List<Student> students = new ArrayList<>(3);
        students.add(new Student("路飞", 22, 175));
        students.add(new Student("红发", 40, 180));
        students.add(new Student("白胡子", 50, 185));

        long count = students.stream().filter(s1 -> s1.getAge() < 45).count();
        System.out.println("年龄小于45岁的人数是：" + count);
    }

    /** TODO **************************************  reduce **************************************  */

    public static void reduce() {
        Integer reduce = Stream.of(1, 2, 3, 4).reduce(0, (acc, x) -> acc+ x);
        System.out.println(reduce);
    }
}
